/**
 * 创建日期: 2017/10/17
 * 创建作者：helloworldyu
 * 文件名称：TcpServerHandler.java
 * 功能:
 */
package com.yhy.tcpserver.inbound;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;
import netty.ChannelManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spring.AppContext;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 功能:tcp数据处理层    转发的格式是 dstDevId,message
 *
 * 文件名称：TcpServerHandler.java
 * 创建日期: 2017/10/17
 * @author helloworldyu
 */
public class TcpServerHandler extends SimpleChannelInboundHandler<String> {

    /**
     * 生成 deviceId
     */
    private static AtomicInteger devId = new AtomicInteger(0);
    private static AttributeKey<String> devIdKey = AttributeKey.valueOf("devId");


    private ChannelManager channelManger = (ChannelManager) AppContext.getBean("channelManger");
    private static final Logger logger = LoggerFactory.getLogger(TcpServerHandler.class);
    //有数据可读的时候触发
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        //处理消息
	    //===获取消息的原id和消息的目标 id=====
        String[] infos = msg.split(",");
        if( infos.length != 2 ){
            ctx.writeAndFlush("数据格式错误");
            return;
        }
	    String dstDevId = infos[0];
        String message = infos[1];
        if( null == dstDevId || null == message ){
            ctx.writeAndFlush("数据格式错误");
            return;
        }
        //==========找到目标id发送===========
        ChannelHandlerContext channelHandlerContext = channelManger.get(dstDevId);
        if( null == channelHandlerContext ){
            ctx.writeAndFlush("目标设备不在线");
            return;
        }
        //===========发送数据================
        channelHandlerContext.channel().writeAndFlush(infos[1]);

        //===========响应数据================
        ctx.channel().writeAndFlush("send ok");
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("设备上线从 channelManger 添加:"+devId.toString());
        channelManger.add(devId.toString(),ctx);
        ctx.channel().attr(TcpServerHandler.devIdKey).set(devId.toString());
        //devId 加 1
        devId.addAndGet(1);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //这个要通过 deviceId 从 channelManger 删除信息。
        //deviceId 可以在在设备登录的时候存到 channel.attr 中。详细的也可以参考
        //https://blog.csdn.net/yuhaiyang457288/article/details/79743963
        String deviceId = ctx.channel().attr(TcpServerHandler.devIdKey).get();
        System.out.println("设备下线从 channelManger 删除:"+deviceId);
        channelManger.remove(deviceId);
    }

    //异常的时候触发
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("{}:异常,栈信息:",ctx.channel().remoteAddress().toString(),cause);
    }

}